package cn.huiyunche.base.service.framework.utils;

import cn.huiyunche.base.service.utils.RandomUtils;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.crypto.codec.Utf8;

public class Md5PasswordEncoderUtils {

    /**
     * 16进制字符集
     */
    private static final char HEX_DIGITS[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D',
            'E', 'F'};

    /**
     * 比较密码一致性
     *
     * @param expected
     * @param actual
     * @return
     */
    public static boolean equals(String expected, String actual) {
        byte[] expectedBytes = bytesUtf8(expected);
        byte[] actualBytes = bytesUtf8(actual);
        int expectedLength = expectedBytes == null ? -1 : expectedBytes.length;
        int actualLength = actualBytes == null ? -1 : actualBytes.length;
        if (expectedLength != actualLength) {
            return false;
        }

        int result = 0;
        for (int i = 0; i < expectedLength; i++) {
            result |= expectedBytes[i] ^ actualBytes[i];
        }
        return result == 0;
    }

    /**
     * 加密
     *
     * @param rawPass 原始密码
     * @return 加密混淆密码
     */
    public static String encodePassword(String rawPass) {
        Md5PasswordEncoder md5 = new Md5PasswordEncoder();
        md5.setIterations(16);
        return md5.encodePassword(rawPass, null);
    }

    /**
     * 获取邀请码
     *
     * @return
     */
    public static String getInvitationCode(String code, int num) {
        String enCodeByMd5 = encodePassword(code);
        byte[] byteArray = enCodeByMd5.getBytes();
        long enCodeBy10 = Long.parseLong(bytesToHex(byteArray, 0, 7), 16);
        String rtnCode = enCodeBy10 + "";
        int len = rtnCode.length();
        if (len >= num) {
            return rtnCode.substring(0, num);
        }
        int count = num - len;
        return rtnCode + RandomUtils.bitInteger(count);
    }

    private static byte[] bytesUtf8(String s) {
        if (s == null) {
            return null;
        }

        return Utf8.encode(s);
    }

    /**
     * * 将字节数组中指定区间的子数组转换成16进制字符串 * @param bytes 目标字节数组 * @param start
     * 起始位置（包括该位置） * @param end 结束位置（不包括该位置） * @return 转换结果
     */
    public static String bytesToHex(byte bytes[], int start, int end) {
        StringBuilder sb = new StringBuilder();
        for (int i = start; i < start + end; i++) {
            sb.append(byteToHex(bytes[i]));
        }
        return sb.toString();
    }

    /**
     * 将单个字节码转换成16进制字符串 * @param bt 目标字节 * @return 转换结果
     */
    public static String byteToHex(byte bt) {
        return HEX_DIGITS[(bt & 0xf0) >> 4] + "" + HEX_DIGITS[bt & 0xf];
    }

    public static void main(String[] args) {
        String s = getInvitationCode("1", 6);
        System.out.println(s);
    }

    /**
     * base64加密
     *
     * @param rawPass 原始密码
     * @return 加密混淆密码
     */
    public static String encodePasswordByBase64(String rawPass) {
        Md5PasswordEncoder md5 = new Md5PasswordEncoder();
        // md5.setIterations(16);
        return md5.encodePassword(rawPass, null);
    }
}
